package org.ysh.demo.shiro;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.util.ByteSource;

/**
 * 自定义认证匹配器
 */
@Slf4j
public class CustomCredentialsMatcher extends HashedCredentialsMatcher {

    public CustomCredentialsMatcher() {
        super(Md5Hash.ALGORITHM_NAME);
        log.info("初始化密码匹配器");
    }

    @Override
    public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
        if (token == null) throw new UnknownAccountException("没有输入账号信息");
        if (info == null) throw new UnknownAccountException("存储中没找到账号信息");

        String inPassword = "";
        if (null != token.getCredentials()) {
            inPassword = new String((char[]) token.getCredentials()); //输入的明文密码
        }

        SimpleAuthenticationInfo uInfo = (SimpleAuthenticationInfo) info; //用户在数据库中的信息(包括身份、证明、盐值)
        ByteSource salt = uInfo.getCredentialsSalt();  //用户存储的盐值
        String saltStr = salt != null ? new String(salt.getBytes()) : "";//盐值转换为原始的字符串

        String ouPassword = new Md5Hash(new Md5Hash(inPassword) + saltStr).toString();//输入的密码进行加密之后的新密码
        log.info("加密密码:[{}],原始密码:[{}]", ouPassword, uInfo.getCredentials());
        return ouPassword.equals(uInfo.getCredentials());
    }
}
